﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace HuntWump2
{
    class Map
    {
        public static bool[] hazardInRoom = new bool[30];
        public static int[] pitRoomNumbers;
        public static int[] batRoomNumbers;
        public static int[] secretsRoomNumbers;
        public static int wumpusRoomNumber;
        public static int playerRoomNumber;
        public static int playerOriginalRoom;

        private static Random rand = new Random();

        private Cave cave;

        public Map()
        {
            // create cave object
            cave = new Cave();

            // set no hazards in any rooms
            for (int i = 0; i < hazardInRoom.Length; i++)
            {
                hazardInRoom[i] = false;
            }

            // create pit rooms (3 of them)
            pitRoomNumbers = new int[3];
            for (int i = 0; i < pitRoomNumbers.Length; i++)
            {
                int room = rand.Next(30);
                if (hazardInRoom[room] == true)
                {
                    i--;
                }
                else
                {
                    hazardInRoom[room] = true;
                    pitRoomNumbers[i] = room;
                }
            }

            // create bat rooms (3 of them)
            batRoomNumbers = new int[3];
            for (int i = 0; i < batRoomNumbers.Length; i++)
            {
                int room = rand.Next(30);
                if (hazardInRoom[room] == true)
                {
                    i--;
                }
                else
                {
                    hazardInRoom[room] = true;
                    batRoomNumbers[i] = room;
                }
            }

            // create 5 secrets rooms
            secretsRoomNumbers = new int[5];
            for (int i = 0; i < secretsRoomNumbers.Length; i++)
            {
                int room = rand.Next(30);
                if (hazardInRoom[room] == true)
                {
                    i--;
                }
                else
                {
                    hazardInRoom[room] = true;
                    secretsRoomNumbers[i] = room;
                }
            }

            // set wumpus room number anywhere
            wumpusRoomNumber = rand.Next(30);
            hazardInRoom[wumpusRoomNumber] = true;

            // set player room number
            playerRoomNumber = rand.Next(30);
            // make sure it's not in a room with a hazard
            while (hazardInRoom[playerRoomNumber] == true)
            {
                playerRoomNumber = rand.Next(30);
            }
            playerOriginalRoom = playerRoomNumber;
        }

        // returns an array of strings with the hazards listed
        // returns null if there are no hazards
        public static List<String> warningsToPlayer()
        {
            List<String> hazards = new List<String>();
            int[] connectedRooms = Cave.connectedRooms(playerRoomNumber);
            for (int i = 0; i < connectedRooms.Length; i++)
            {
                if (hazardInRoom[connectedRooms[i]] == true)
                {
                    for (int j = 0; j < pitRoomNumbers.Length; j++)
                    {
                        if (connectedRooms[i] == pitRoomNumbers[j])
                        {
                            hazards.Add("Pit");
                        }
                    }
                    for (int j = 0; j < batRoomNumbers.Length; j++)
                    {
                        if (connectedRooms[i] == batRoomNumbers[j])
                        {
                            hazards.Add("Bat");
                        }
                    }
                    if (connectedRooms[i] == wumpusRoomNumber)
                    {
                        hazards.Add("Wumpus");
                    }
                }
            }
            return hazards;
        }

        // returns 0 for a pit, 1 for a bat, 2 for a secret, and -1 for nothing in the room
        public static int hazardInARoom(int roomNumber)
        {
            for (int i = 0; i < pitRoomNumbers.Length; i++)
            {
                if (pitRoomNumbers[i] == roomNumber) return 0;
            }
            for (int i = 0; i < batRoomNumbers.Length; i++)
            {
                if (batRoomNumbers[i] == roomNumber) return 1;
            }
            for (int i = 0; i < secretsRoomNumbers.Length; i++)
            {
                if (secretsRoomNumbers[i] == roomNumber) return 2;
            }
            return -1;
        }

        public static bool wumpusInPlayerRoom()
        {
            if (wumpusRoomNumber == playerRoomNumber) return true;
            return false;
        }

        // This method moves the wumpus to an adjacent room
        // To be used when the wumpus needs to move, but is not running away multiple rooms
        public static void moveWumpus()
        {
            int originalRoom = wumpusRoomNumber;
            int[] wumpusAdjacentRooms = Cave.connectedRooms(wumpusRoomNumber);
            int pickRoomNumber = rand.Next(wumpusAdjacentRooms.Length);
            wumpusRoomNumber = wumpusAdjacentRooms[pickRoomNumber];

            // set the new wumpus room to containing a hazard
            hazardInRoom[wumpusRoomNumber] = true;

            // set the original room to not containing a hazard unless a bat or cave is in the room
            bool hazard = false;
            for (int i = 0; i < pitRoomNumbers.Length; i++)
            {
                if (pitRoomNumbers[i] == originalRoom)
                {
                    hazard = true;
                }
            }
            for (int i = 0; i < batRoomNumbers.Length; i++)
            {
                if (batRoomNumbers[i] == originalRoom)
                {
                    hazard = true;
                }
            }
            hazardInRoom[originalRoom] = hazard;
        }

        // This method moves the wumpus 2-4 rooms away
        public static void runAwayWumpus()
        {
            // creates array of random lenth between 2 and 4
            // will be used to keep track of the number of rooms left to move
            // and to test to make sure the Wumpus does not go back into one of the previous rooms
            int[] roomsTravelingThrough = new int[rand.Next(3) + 2];
            roomsTravelingThrough[0] = wumpusRoomNumber;

            // creates a for loop that moves the wumpus enough times to fill the array, and then one final move into the final room
            for (int i = 0; i < roomsTravelingThrough.Length + 1; i++)
            {
                int[] wumpusAdjacentRooms = Cave.connectedRooms(wumpusRoomNumber);
                int pickRoomNumber = rand.Next(wumpusAdjacentRooms.Length);
                // assures the room that the wumpus is moving into has more than one door
                while (Cave.rooms[pickRoomNumber].getNumDoors() == 1)
                {
                    pickRoomNumber = rand.Next(wumpusAdjacentRooms.Length);
                }

                // assures that the room the wumpus is moving into is not a room it has previously gone into
                // (there is a possibility it could be caught in an endless loop, so if it generates a previous room number five times in a row, it stops moving)
                int testForEndlessLoop = 5;
                for (int j = 0; j < i; j++)
                {
                    if (roomsTravelingThrough[j] == wumpusAdjacentRooms[pickRoomNumber] && testForEndlessLoop > 0)
                    {
                        pickRoomNumber = rand.Next(wumpusAdjacentRooms.Length);
                        j = 0;
                        testForEndlessLoop--;
                    }
                }
                if (testForEndlessLoop == 0) break;

                wumpusRoomNumber = wumpusAdjacentRooms[pickRoomNumber];
            }
            // set the new wumpus room to containing a hazard
            hazardInRoom[wumpusRoomNumber] = true;

            // set the original room to not containing a hazard unless a bat or cave is in the room
            bool hazard = false;
            for (int i = 0; i < pitRoomNumbers.Length; i++)
            {
                if (pitRoomNumbers[i] == roomsTravelingThrough[0])
                {
                    hazard = true;
                }
            }
            for (int i = 0; i < batRoomNumbers.Length; i++)
            {
                if (batRoomNumbers[i] == roomsTravelingThrough[0])
                {
                    hazard = true;
                }
            }
            hazardInRoom[roomsTravelingThrough[0]] = hazard;
        }

        // this method is to be called when the player is carried away by a bat
        // it sets the bat room number to a new location (and changes the number in the array of batRoomNumbers
        // and then sets the player room number to a new, different location
        public static void moveBat()
        {
            int room = playerRoomNumber;
            int newBatRoomNumber = rand.Next(30);
            while (newBatRoomNumber == room || hazardInRoom[newBatRoomNumber] == true)
            {
                newBatRoomNumber = rand.Next(30);
            }
            for (int i = 0; i < batRoomNumbers.Length; i++)
            {
                if (batRoomNumbers[i] == room) batRoomNumbers[i] = newBatRoomNumber;
            }

            int newPlayerRoomNumber = rand.Next(30);
            while (newPlayerRoomNumber == room || newPlayerRoomNumber == newBatRoomNumber)
            {
                newPlayerRoomNumber = rand.Next(30);
            }

            if (wumpusRoomNumber != room) hazardInRoom[room] = false;
            hazardInRoom[newBatRoomNumber] = true;

            playerRoomNumber = newPlayerRoomNumber;
        }
    }
}
